#include "gf_math.h"

unsigned char gf_add(unsigned char a, unsigned char b) {
	return (a ^ b);
}

unsigned char gf_sub(unsigned char a, unsigned char b) {
	return gf_add(a, b);
}

unsigned char gf_mult(unsigned char a, unsigned char b) {
        unsigned char p = a;
        int wt = (b >> 3) ^ (1 & (b >> 2)) ^ (1 & (b >> 1)) ^ (1 & b);

        p ^= a << (3 * (1 & ( b >> 3)));
        p ^= a << (2 * (1 & ( b >> 2)));
        p ^= a <<      (1 & ( b >> 1));
        p ^= a*wt;

        return (0x0F & p);
}

unsigned char parity(unsigned char a, unsigned b) {
	int count = 0;

	for(int i = 1; i < 16; i <<= 1) {
		if(((a & i) > 0) && ((b & i) > 0))
			++count;
	}

	return count;
}

char fc(unsigned char *sbox, unsigned char a, unsigned char b) {
	char retval = 0;
	unsigned char x;

	for(x = 0; x < 16; ++x) {
		if((parity(b, sbox[x]) ^ parity(a, x)) % 2 == 0)
			++retval;
		else
			--retval;
	}

	return retval;
}
